<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>dkone game</title>
<style>
  /*小屏设备*/
  @media (min-width:0px) and (max-width:768px) {
    .frame{
      height: 404px;
      width: 720px;
      display: grid;
      grid-template-rows: 20% 80%;
    }
  }
  
  
  @media (min-width:769px) and (max-width:992px) {
    .frame{
      display: grid;
      height: 440px;
      width: 769px;
      grid-template-rows: 20% 80%;
    }
  }
  
  @media (min-width:993px) {
    .frame{
      display: grid;
      height: 520px;
      width: 993px;
      grid-template-rows: 20% 80%;
    }
  }
  
  .interact_zone{
    display: grid;
    grid-template-columns: 5% 20% 45% 20% 10%;
  }

  .board{
    display: grid;
    grid-template-rows: repeat(4, 1fr);
    grid-template-columns: repeat(4, 1fr);
  }
  
  .buttons{
    display: grid;
    place-items: center;
  }
  
  .title{
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  .vacancy{
    aspect-ratio: 1 / 1;
    border: 2px solid gray;
  }
  
  .button {
    display: inline-block;
    padding: 10px 20px; /* 自定义内边距 */
    border: none; /* 移除边框 */
    border-radius: 4px; /* 圆角边框 */
    background-color: #f1f1f1; /* 背景颜色 */
    color: #000000; /* 文字颜色 */
    text-align: center; /* 文字居中 */
    text-decoration: none; /* 去除文字装饰效果 */
    transition: background-color 0.3s ease; /* 过渡动画效果 */
    cursor: pointer; /* 鼠标指针样式为手型 */
  }

  .button:hover {
    background-color: #eaeaea; /* 鼠标悬停时的背景颜色 */
  }

  .button:active {
    background-color: #dcdcdc; /* 按下时的背景颜色 */
  }
  
  .alert {
    padding: 10px;
    margin-top: 10px;
    box-shadow: 0 0 5px gray;
  }

  .alert-normal {
    color: #000000;
  }
  
  .red {
    background-color: red;
  }
  
  .cyan {
    background-color: cyan;
  }
  
  #myColor {
    width: 100px;
    height: 100px;
  }
</style>
<script>
    function showAlert(message, type = 'normal') {
      let info = document.createElement('div');
      info.classList.add('alert', `alert-${type}`);
      info.innerText = message;
      document.querySelector('.hint').appendChild(info);
      setTimeout(() => {
        info.remove();
      }, 1500);
    }
    
    function getAjax(){
      return new XMLHttpRequest();
    }
    
    //锁定当前棋盘状态
    function frozenBoard(){
      Array.from(document.querySelectorAll('.vacancy')).forEach(vacancy => {
        vacancy.style.pointerEvents = 'none';
      });
    }

    //解锁当前棋盘状态
    function unfrozenBoard(){
      Array.from(document.querySelectorAll('.vacancy')
      ).forEach(vacancy => {
        vacancy.style.pointerEvents = 'auto';
      });
    }

    /*
    * 检查对手是否已落子
    * @param {string} playerName 当前玩家名
    */
    function checkDrop(playerName){
      let roomId = localStorage.getItem('roomId');
      let myColor = document.querySelector('#myColor');
      let ajax = getAjax();
      let query = `roomId=${roomId}`;
      ajax.timeout = 60000;
      ajax.ontimeout=function(){
        let isWait = confirm('对方已1min未操作，是否继续等待？');
        if(isWait)
          checkDrop(playerName);
        else
          unfrozenBoard();
      }
      ajax.onreadystatechange = function(){
        if(ajax.readyState == 4 && ajax.status == 200){
          let resp = JSON.parse(ajax.responseText);
          if(resp.accept ==playerName ){
            let remove = resp.removeList;
            let dropLocation = resp.dropLocation;
            eliminate(remove);
            fillPosition(dropLocation,notColor(myColor.className));
            unfrozenBoard();
            myColor.innerHTML = '轮到你了';
          }else{
            checkDrop(playerName);
          }
          checkWin(roomId);
        }
      }
      ajax.open('GET', origin+'/checkDrop?'+query );
      ajax.send();

    }

    //检查是否有赢家出现
    function checkWin(roomId){
      let ajax = getAjax();
      let query = `roomId=${roomId}`;

      ajax.onreadystatechange = function(){
        if(ajax.readyState == 4 && ajax.status == 200){
          let resp = JSON.parse(ajax.responseText);
          if(resp.winner){ // 已有赢家出现
            frozenBoard();
            let info = `玩家${resp.winner}已胜利`;
            document.querySelector('#myColor').innerHTML = info;
          }
        }
      }

      ajax.ontimeout = ()=>{
        console.log('没有检测到赢家');
      }
      
      ajax.open('GET',origin+'/checkWin?'+query);
      ajax.send();
    }

    //根据id数组移除棋子
    function eliminate(remove){
      remove.length > 0 && remove.forEach(id => {
        let vacancy = document.getElementById(id);
        vacancy.className = 'vacancy';
      });
    }

    //根据id数组填充棋子
    function fillPosition(oppo,color){
        let vacancy = document.getElementById(oppo);
        vacancy.className = color;
    }

    //返回相反颜色
    function notColor(color){
      return color == 'red'? 'cyan' : 'red';
    }
    
    window.onload = function(){
      frozenBoard();
      let playerName = localStorage.getItem('playerName');
      let roomId = localStorage.getItem('roomId');
      let myColor = document.querySelector('#myColor');
      let queryRoom = getAjax();
      let query = `playerName=${playerName}&roomId=${roomId}`;
      let vacancies = document.querySelectorAll('.vacancy');
      
      /*页面信息完善，填充执手颜色、明确先手和后手*/
      //根据查询得到的信息渲染执手颜色
      queryRoom.onreadystatechange = function(){
        if(this.readyState == 4 && this.status == 200){
          let resp = JSON.parse(this.responseText);
          console.log(`former:${resp.former} player:${playerName}`);
          if(resp.former == playerName){ //确定为先手，设定当前颜色为红色，解锁棋盘
            myColor.className='red';
            myColor.innerHTML = "轮到你了";
            unfrozenBoard();
          }else{
            myColor.className='cyan';
            myColor.innerHTML = "等待对手落子";
            checkDrop(playerName);
          }
        }
      }
      queryRoom.open('GET',origin+'/checkRoom?'+query);
      queryRoom.send();
      
      /*绑定棋子空位点击事件*/
      Array.from(vacancies).forEach(function(vacancy){
        vacancy.addEventListener('click',function(e){
          if(this.classList.contains('red') || this.classList.contains('cyan')){
            console.log('Vacancy %s has been occupied',this.id);
          }else{
            //将落子渲染到棋盘
            this.classList.add(myColor.className);
            myColor.innerHTML = '等待对手落子';

            //锁定当前棋盘状态
            frozenBoard();
            //发送请求playerName、this.id
            let ajax = getAjax();
            let paramString = `playerName=${playerName}&locate=${this.id}`;
            //绑定响应渲染消子
            ajax.onreadystatechange = function(){
              if(this.readyState == 4 && this.status == 200){
                let removeList = JSON.parse(this.responseText);
                eliminate(removeList);
                checkWin(roomId);
              }
            }
                   
            ajax.open('GET',origin+'/drop?'+paramString);
            ajax.send();

            //确认是否有赢家出现
            
            //检查对手落子
            checkDrop(playerName);
            
          }
        });
      });
    }
</script>
</head>
<body>
  <div class="frame">
    <div class="title"><h1>dkone</h1></div>
    <div class="interact_zone">
      <div></div>
      <div class="hint">
        <div>我方棋色</div>
        <div id="myColor"></div>
      </div>
      <div class="board">
        <div class="vacancy" id="r0c0"></div>
        <div class="vacancy" id="r0c1"></div>
        <div class="vacancy" id="r0c2"></div>
        <div class="vacancy" id="r0c3"></div>
        <div class="vacancy" id="r1c0"></div>
        <div class="vacancy" id="r1c1"></div>
        <div class="vacancy" id="r1c2"></div>
        <div class="vacancy" id="r1c3"></div>
        <div class="vacancy" id="r2c0"></div>
        <div class="vacancy" id="r2c1"></div>
        <div class="vacancy" id="r2c2"></div>
        <div class="vacancy" id="r2c3"></div>
        <div class="vacancy" id="r3c0"></div>
        <div class="vacancy" id="r3c1"></div>
        <div class="vacancy" id="r3c2"></div>
        <div class="vacancy" id="r3c3"></div>
      </div>
      <div class="buttons">
        <div class="button">重新开始</div>
        <div class="button">执行悔棋</div>
        <div class="button">退出游戏</div>
      </div>
      <div></div>
    </div>
  </div>
</body>
</html>